import { GOODS_LIST } from "@/route";
import { Button, Form, FormInstance, Input, Select, Switch, Image, message } from "antd";
import { history } from "@/util/history";
import { LeftOutlined } from "@ant-design/icons";
import { createContext, createRef, RefObject, useContext, useEffect, useMemo, useRef, useState } from "react";
import ImgUpload from "@/components/dataEntry/ImgUpload";
import { useSearchParams } from "react-router-dom";
import { getSource, GetSourceParams } from "@/api";
import { PageData } from "@/util";
import { CategoryRecord } from "../Category/CategoryType";
import { AppContext } from "@/providers";
import { debounce } from "lodash";
import AttributeTable, { AttributeTableRecord, AttributeTableRef } from "./components/AttributeTable";
import SkuTable, { SkuTableRef } from "./components/SkuTable/SkuTable";
import { createGoods, getGoods, updateGoods } from "@/api/goods";
import { SkuAttribute } from "@/typings/goods";
import { getSkuValue } from "./components/SkuTable/components/SkuFormList/components/SkuSelect";
import { StyledGoodsFormWrapper } from "./styled";

export interface OperateGoodsContextProps {
	skuOptions: AttributeTableRecord[];
	setSkuOptions: (options: AttributeTableRecord[]) => void;
	skuOptionRef: RefObject<AttributeTableRef>;
}
export const OperateGoodsContext = createContext<OperateGoodsContextProps>({
	skuOptions: [],
	setSkuOptions: () => null,
	skuOptionRef: createRef(),
});

const OperateGoods = () => {
	const { REACT_APP_BASEURL } = useContext(AppContext);
	const baseFormRef = useRef<FormInstance>(null);
	const skuTableRef = useRef<SkuTableRef>(null);
	const [params] = useSearchParams();
	const type = useMemo<string | null>(() => params.get("type"), []);
	const goodsId = useMemo<string | null>(() => params.get("id"), []);
	const [category, setCategory] = useState<CategoryRecord[]>([]);
	const fetchCategory = async (name = "") => {
		const query: GetSourceParams = {
			source: "category",
			page: 1,
			pageSize: 9999,
			name: { value: name, like: true },
		};
		const res = await getSource<PageData<CategoryRecord[]>>(query);
		setCategory(res.data?.data || []);
	};
	const fetchCategoryDebounce = debounce(fetchCategory, 600);
	const fetchGoods = async (id: string) => {
		const goods = (await getGoods({ id }))?.data?.data;
		if (!goods?.length) return;
		const { sku, spu, status, categories = [], ...remainGoodsProps } = goods[0];
		baseFormRef.current?.setFieldsValue({
			...remainGoodsProps,
			status: status === 1 ? true : false,
			categories: categories.map((item) => item._id),
		});
		const spuList = Object.entries(spu).map(([key, value], rowIndex) => ({
			key,
			valueList: value.map((item) => ({ ...item, rowIndex })),
		}));
		// const skuList = sku.map((item) => ({ ...item, images: item.images ? item.images?.split(",") : [] }));
		const attributeList = sku.reduce((pre: SkuAttribute[], item) => [...pre, ...item.attributes], []);
		spuRef.current?.setData(spuList);
		skuTableRef.current?.setData(sku);
		const skuOptionsList: AttributeTableRecord[] = [];
		attributeList.forEach((item) => {
			const keyList = skuOptionsList.map((item1) => item1.key);
			!keyList.includes(item.key) && skuOptionsList.push({ key: item.key, valueList: [] });
		});
		skuOptionsList.forEach((item, rowIndex) => {
			attributeList.forEach((item1) => {
				if (item.key === item1.key) {
					const itemSkuValueList = item.valueList.map((item2) => getSkuValue(item2.name, item2.image));
					const item1SkuValue = getSkuValue(item1.value.name, item1.value.image);
					if (!itemSkuValueList.includes(item1SkuValue)) {
						item.valueList.push({ name: item1.value.name, image: item1.value.image, rowIndex });
					}
				}
			});
		});
		setSkuOptions(skuOptionsList);
		skuOptionRef.current?.setData(skuOptionsList);
	};
	useEffect(() => {
		goodsId && fetchGoods(goodsId);
		fetchCategory();
	}, []);
	const spuRef = useRef<AttributeTableRef>(null);
	const skuOptionRef = useRef<AttributeTableRef>(null);
	const [skuOptions, setSkuOptions] = useState<AttributeTableRecord[]>([]);

	return (
		<OperateGoodsContext.Provider value={{ skuOptions, setSkuOptions, skuOptionRef }}>
			<div className="relative h-full">
				<Button icon={<LeftOutlined />} shape="round" className="mb-2" onClick={() => history.replace(GOODS_LIST)}>
					返回列表
				</Button>
				<StyledGoodsFormWrapper className="overflow-y-scroll">
					<h2 className="ml-24 my-4">{type === "add" ? "添加" : type === "edit" ? "编辑" : "克隆"}商品</h2>
					<Form
						ref={baseFormRef}
						labelCol={{ style: { width: "120px" } }}
						wrapperCol={{ span: 24 }}
						style={{ width: "700px" }}
						initialValues={{ status: true, category: [], cover: "", description: "" }}
					>
						<Form.Item label="商品名" name="name" rules={[{ required: true, message: "请输入商品名" }]}>
							<Input placeholder="请输入商品名" style={{ width: "300px" }} />
						</Form.Item>
						<Form.Item label="商品封面" name="cover">
							<ImgUpload formRef={baseFormRef} field="cover" />
						</Form.Item>
						<Form.Item label="商品描述" name="description">
							<Input.TextArea placeholder="请输入商品描述" maxLength={500} showCount rows={3} />
						</Form.Item>
						<Form.Item label="状态" name="status" valuePropName="checked">
							<Switch checkedChildren="上架" unCheckedChildren="下架" />
						</Form.Item>
						<Form.Item label="分类" name="categories">
							<Select
								style={{ width: "300px" }}
								allowClear
								onClear={fetchCategoryDebounce}
								showSearch
								onSearch={fetchCategoryDebounce}
								placeholder="选择或搜索分类"
								filterOption={false}
								mode="multiple"
								options={category.map((item) => ({
									label: (
										<div className="flex">
											{item.cover && (
												<Image
													height={25}
													width={30}
													style={{ objectFit: "cover" }}
													src={`${REACT_APP_BASEURL}${item.cover}`}
												/>
											)}
											<div className="ml-2">{item.name}</div>
										</div>
									),
									value: item._id,
								}))}
							/>
						</Form.Item>
					</Form>
					<Form labelCol={{ style: { width: "120px" } }} wrapperCol={{ span: 22 }}>
						<Form.Item label="公共属性(spu)">
							<AttributeTable ref={spuRef} label="spu" />
						</Form.Item>
						<Form.Item label="商品规格(sku)">
							<SkuTable ref={skuTableRef} />
						</Form.Item>
					</Form>
				</StyledGoodsFormWrapper>
				<div className="absolute bottom-2 w-full flex justify-center">
					<Button
						type="primary"
						style={{ width: "140px" }}
						onClick={async () => {
							const formData = await baseFormRef.current?.validateFields();
							const list = spuRef.current?.getData() || [];
							const spu = list
								.map((listItem) => ({ [listItem.key]: listItem.valueList.map(({ image, name }) => ({ image, name })) }))
								.reduce((pre, item) => ({ ...pre, ...item }), {});
							const sku = skuTableRef.current?.getData();
							const body = { ...formData, spu, sku, status: formData.status ? 1 : 0 };
							if (["add", "clone"].includes(type || "")) {
								await createGoods(body);
								message.success("创建成功"); 
								setTimeout(() => {
									history.push(GOODS_LIST);
								}, 500);
							}
							if (type === "edit") {
								await updateGoods({ ...body, id: goodsId });
								message.success("编辑成功");
							}
						}}
					>
						提交
					</Button>
				</div>
			</div>
		</OperateGoodsContext.Provider>
	);
};

export default OperateGoods;
